package xj.graph2d.tools;

import java.awt.Graphics2D;
import java.awt.Point;
import java.awt.geom.Point2D;
import java.util.Observer;

import xj.graph2d.Command;
import xj.graph2d.DrawCanvas;
import xj.graph2d.DrawShape;
import xj.graph2d.DrawShapeConstants;
import xj.graph2d.DrawShapeFactory;
import xj.graph2d.command.AddShapeCommand;
import xj.graph2d.shapes.CircleShape;
import xj.util.gui.Point2DFloat;

public class CircleDrawTool extends SimpleDrawTool {

  public CircleDrawTool() {
    this(null, DrawShapeConstants.USE_SYSTEM_DRAW_ATTR);
  }

  public CircleDrawTool(int cloneDrawAttrMode) {
    this(null, cloneDrawAttrMode);
  }

  public CircleDrawTool(CircleShape proto) {
    this(proto, DrawShapeConstants.USE_SYSTEM_DRAW_ATTR);
  }

  public CircleDrawTool(CircleShape proto, int cloneDrawAttrMode) {
    super(cloneDrawAttrMode);
    if (proto != null) {
      this.proto = proto;
    } else {
      this.proto = new CircleShape();
    }
  }

  @Override
  public void mouseLButtonPressed(Observer observer, Point p, int modifiers) {
    mouseButtonDown = true;
    start(observer);
    if (view != null) {
      Graphics2D g2 = canvas.getGraphics2D();
      DrawShape selected = doc.getSelectedShape();

      doc.setSelectedShape(null);

      canvas.repaint();

      canvas.setEditingMode(true);
      prev = view.physicalToVirtual(p);
      float x = (float) prev.getX();
      float y = (float) prev.getY();
      start = new Point2DFloat(x, y);
      g2.setXORMode(view.getBackgroundColor());
      canvas.setTransform(g2);
      shape = (CircleShape) DrawShapeFactory.cloneDrawShape(proto, view,
	  cloneDrawAttrMode);
      shape.drawOutline(g2, x, y, x, y);
      g2.dispose();
    }
  }

  @Override
  public void mouseLButtonReleased(Observer observer, Point p, int modifiers) {
    if (mouseButtonDown && shape != null && view != null) {
      Graphics2D g2 = canvas.getGraphics2D();
      canvas.setEditingMode(false);
      Point2D cur = view.physicalToVirtual(p);
      float x0 = (float) start.getX();
      float y0 = (float) start.getY();
      float x1 = (float) cur.getX();
      float y1 = (float) cur.getY();
      if (Math.abs(x1 - x0) >= 1f && Math.abs(y1 - y0) >= 1f) {
	shape.setCircle(x0, y0, x1, y1);

	Command cmd = new AddShapeCommand(view, doc, shape);
	doc.executeCommand(cmd);
	//
	// doc.add(newShape, true);

	switchTool();
      }

      // canvas.repaint(newShape);
      // canvas.repaint();
      g2.dispose();
    }
    mouseButtonDown = false;
  }

  @Override
  public void mouseDragged(Observer observer, Point p, int modifiers) {
    if (view != null) {
      displayLocation(p);
      view.displayHelpMessage(MSGKEY_2);

      Graphics2D g2 = canvas.getGraphics2D();
      if (mouseButtonDown && shape != null) {
	Point2D cur = view.physicalToVirtual(p);
	g2.setXORMode(view.getBackgroundColor());
	canvas.setTransform(g2);
	shape.drawOutline(g2, (float) start.getX(), (float) start.getY(),
	    (float) prev.getX(), (float) prev.getY());
	shape.drawOutline(g2, (float) start.getX(), (float) start.getY(),
	    (float) cur.getX(), (float) cur.getY());
	prev = cur;
      }
      g2.dispose();
    }
  }

  @Override
  public void mouseRButtonPressed(Observer observer, Point p, int modifiers) {
    start(observer);
    if (view != null) {
      DrawCanvas canvas = view.getCanvas();

      DrawShape prevSelectedShape = doc.getSelectedShape();
      if (prevSelectedShape != null) {
	doc.setSelectedShape(null);
	canvas.repaintShape(prevSelectedShape, true);
      }

    }

  }

  @Override
  public void mouseMoved(Observer observer, Point p, int modifiers) {
    if (view != null) {
      displayLocation(p);
      view.displayHelpMessage(MSGKEY_1);
    }
  }

  protected static final String MSGKEY_1 = "CircleTool.message.1";

  protected static final String MSGKEY_2 = "CircleTool.message.2";

  protected Point2D start;

  protected CircleShape shape;

  protected CircleShape proto;

}
